<!doctype html>
<html>
<head>
    <meta charset="utf-8">
    <title>Force Atlas2 - ECHARTS-GL</title>
    <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
    <meta name="apple-mobile-web-app-capable" content="yes"> <!-- Fullscreen Landscape on iOS -->
    <link rel="stylesheet" href="./common.css">
</head>
<body>
<script src="../node_modules/echarts/dist/echarts.js"></script>
<script src="../node_modules/echarts/dist/extension/dataTool.js"></script>
<script src="../dist/echarts-gl.js"></script>
<script src="lib/jquery.min.js"></script>
<script src="js/commonUI.js"></script>
<script>
    var forceAtlas = new echarts.ForceAtlas2GPU();

    var renderer = new echarts.graphicGL.Renderer();

    function createNodes(widthCount, heightCount) {
        var nodes = [];
        for (var i = 0; i < widthCount; i++) {
            for (var j = 0; j < heightCount; j++) {
                nodes.push({
                    x: Math.random() * window.innerWidth,
                    y: Math.random() * window.innerHeight
                });
            }
        }
        return nodes;
    }

    function createEdges(widthCount, heightCount) {
        var edges = [];
        for (var i = 0; i < widthCount; i++) {
            for (var j = 0; j < heightCount; j++) {
                if (i < widthCount - 1) {
                    edges.push({
                        node1: i + j * widthCount,
                        node2: i + 1 + j * widthCount,
                        weight: 2
                    });
                }
                if (j < heightCount - 1) {
                    edges.push({
                        node1: i + j * widthCount,
                        node2: i + (j + 1) * widthCount,
                        weight: 2
                    });
                }
            }
        }
        return edges;
    }

    var nodes = createNodes(100, 100);
    var edges = createEdges(100, 100);
    forceAtlas.initData(nodes, edges);
    forceAtlas.updateOption({
        gravityCenter: [window.innerWidth / 2, window.innerHeight / 2],
        gravity: 4,
        scaling: 0.4,
        edgeWeightInfluence: 2
    });

    var canvas = document.createElement('canvas');
    canvas.width = window.innerWidth;
    canvas.height = window.innerHeight;
    var ctx = canvas.getContext('2d');
    document.body.appendChild(canvas);

    var debugCanvas = document.createElement('canvas');
    var debugCtx = debugCanvas.getContext('2d');
    debugCanvas.style.cssText = 'position:absolute;left:0;top:0;';
    document.body.appendChild(debugCanvas);

    function step() {
        console.time('layout');
        for (var i = 0; i < 1; i++) {
            forceAtlas.step(renderer);
        }
        console.timeEnd('layout');

        var data = forceAtlas.getTextureData(renderer, 'position');
        var textureSize = forceAtlas.getTextureSize();
        debugCanvas.width = textureSize.width;
        debugCanvas.height = textureSize.height;
        var imageData = debugCtx.createImageData(textureSize.width, textureSize.height);
        for (var i = 0; i < data.length / 4; i++) {
            var i4 = i * 4;
            imageData.data[i4] = data[i4];
            imageData.data[i4 + 1] = data[i4 + 1];
            imageData.data[i4 + 2] = 0;
            imageData.data[i4 + 3] = 255;
        }

        debugCtx.putImageData(imageData, 0, 0);

        drawDebug();

        setTimeout(step, 1000);
    }

    setTimeout(step, 10);

    var nodePosition = new Float32Array(nodes.length * 2);

    // Debug
    function drawDebug() {
        // console.log(forceAtlas.getTextureData(renderer, 'forcePrev'));
        forceAtlas.getNodePosition(renderer, nodePosition);
        console.time('render');
        ctx.clearRect(0, 0, canvas.width, canvas.height);
        ctx.beginPath();
        ctx.fillStyle = 'rgba(255, 255, 255, 0.7)';
        for (var i = 0; i < nodes.length; i++) {
            var x = nodePosition[i * 2];
            var y = nodePosition[i * 2 + 1]
            ctx.rect(x - 2, y - 2, 4, 4);
        }
        ctx.fill();
        ctx.strokeStyle = 'rgba(255, 255, 255, 0.2)';
        ctx.lineWidth = 1;
        ctx.beginPath();
        for (var i = 0; i < edges.length; i++) {
            var edge = edges[i];
            var x0 = nodePosition[edge.node1 * 2];
            var y0 = nodePosition[edge.node1 * 2 + 1];
            var x1 = nodePosition[edge.node2 * 2];
            var y1 = nodePosition[edge.node2 * 2 + 1];

            ctx.moveTo(x0, y0);
            ctx.lineTo(x1, y1);
        }
        ctx.stroke();
        console.timeEnd('render');
    }
</script>
</body>
</html>
